﻿///////////////////////////////////////////////////////////////////////////////
// File Name: SkinMainWnd.cpp
// Author: 张东斌、ChongyangLee, lynnux
// E_Mail: malutianshi7905@sina.com; ChongyangLee@hotmail.com; lynnux@yeah.net
// History: 
// 2009/11/21: 增加标题栏的鼠标右键响应 OnNcRButtonDown
// 
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SkinMainWnd.h"

#include <WinUser.h>

CSkinFrame::CSkinFrame(void)
{
	m_bEnableSkin = TRUE;
	m_bMDI = FALSE;
	m_bInMenu = FALSE;
}

CSkinFrame::~CSkinFrame(void)
{
	if(m_bHScroll || m_bVScroll)
		UninitializeSB(m_hWnd);
	HookWindow((HWND)NULL);
}
BOOL CSkinFrame::LoadSkin()
{
    m_pSkinWindow = GetSkin().GetWindowSkin();
    if (!m_pSkinWindow)
    {
        return FALSE;
    }
    SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
    return TRUE;
}
BOOL CSkinFrame::InstallSkin(HWND hWnd)
{
	if(!hWnd || !LoadSkin())
        return FALSE;   
	HookWindow( (HWND)NULL);
	int r = HookWindow( hWnd );

#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
	LONG_PTR exstyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
	DWORD exstyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
#endif
	m_bBorder		= HAS_ANYFRAME(style,exstyle);
	m_bSizable		= HAS_THICKFRAME(style,exstyle);
	m_bMinBtn		= style & WS_MINIMIZEBOX;
	m_bMaxBtn		= style & WS_MAXIMIZEBOX;
	m_bSysMenu		= style & WS_SYSMENU;
	m_bTitle		= style & WS_CAPTION;
	m_bCloseBtn		= m_bSysMenu;
	m_bHScroll		= style & WS_HSCROLL;
	m_bVScroll		= style & WS_VSCROLL;
	m_bLeftScroll	= exstyle & WS_EX_LEFTSCROLLBAR;			 	

	HMENU  hMenu = GetMenu(hWnd);
	if(((style & (WS_CHILD | WS_POPUP) )!= WS_CHILD)&&hMenu)
		m_bMenu =  TRUE;
	else
		m_bMenu = FALSE;

	if(m_bMenu)
	{
		m_bHasMenu = TRUE;
		m_menuBar.SetMenu(hMenu,m_hWnd);
		
	}
	style &= ~WS_MINIMIZEBOX;
	style &= ~WS_MAXIMIZEBOX;
//	style &= ~WS_SYSMENU;
	style &= ~WS_THICKFRAME;
	style &= ~WS_CAPTION;
	style &= ~WS_BORDER;
	style &= ~WS_DLGFRAME;
	exstyle &= ~WS_EX_DLGMODALFRAME;
#ifdef _WIN64
	SetWindowLongPtr(m_hWnd, GWL_STYLE, style);
	SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exstyle);
#else
	SetWindowLong(m_hWnd, GWL_STYLE, style);
	SetWindowLong( m_hWnd, GWL_EXSTYLE, exstyle );
#endif

	InitializeSB(m_hWnd);

	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
	return TRUE;
}

 BOOL CSkinFrame::InstallSkin(HWND hWnd,const CString& strSkinName)
{
	if(!hWnd || strSkinName.IsEmpty())
		return FALSE;

	CObjectSkin* pObjectSkin = GetSkin().FindObjectSkin(strSkinName);
	if(pObjectSkin)
	{
		if(pObjectSkin->GetSkinType() == keWindowSkin)
			m_pSkinWindow = (CWindowSkin*)pObjectSkin;
	}
	else
		m_pSkinWindow = GetSkin().GetWindowSkin();
	if(!m_pSkinWindow)
	{
		m_bEnableSkin = FALSE;
		return FALSE;
	}
	m_bEnableSkin = TRUE;
	HookWindow( (HWND)NULL);
	int r = HookWindow( hWnd );

#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
	LONG_PTR exstyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
	DWORD exstyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
#endif
	m_bBorder		= HAS_ANYFRAME(style,exstyle);
	m_bSizable		= HAS_THICKFRAME(style,exstyle);
	m_bMinBtn		= style & WS_MINIMIZEBOX;
	m_bMaxBtn		= style & WS_MAXIMIZEBOX;
	m_bSysMenu		= style & WS_SYSMENU;
	m_bTitle		= style & WS_CAPTION;
	m_bCloseBtn		= m_bSysMenu;
	m_bHScroll		= style & WS_HSCROLL;
	m_bVScroll		= style & WS_VSCROLL;
	m_bLeftScroll	= exstyle & WS_EX_LEFTSCROLLBAR;			 	

	HMENU  hMenu = GetMenu(hWnd);
	if(((style & (WS_CHILD | WS_POPUP) )!= WS_CHILD)&&hMenu)
		//if(hMenu)
		m_bMenu =  TRUE;
	else
		m_bMenu = FALSE;

	if(m_bMenu)
	{
		m_bHasMenu = TRUE;
		m_menuBar.SetMenu(hMenu,m_hWnd);

	}
	style &= ~WS_MINIMIZEBOX;
	style &= ~WS_MAXIMIZEBOX;
	style &= ~WS_SYSMENU;
	style &= ~WS_THICKFRAME;
	style &= ~WS_CAPTION;
	style &= ~WS_BORDER;
	style &= ~WS_DLGFRAME;
	exstyle &= ~WS_EX_DLGMODALFRAME;
#ifdef _WIN64
	SetWindowLongPtr(m_hWnd, GWL_STYLE, style);
	SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, exstyle);
#else
	SetWindowLong(m_hWnd, GWL_STYLE, style);
	SetWindowLong(m_hWnd, GWL_EXSTYLE, exstyle);
#endif

	InitializeSB(m_hWnd);

	SetWindowPos(m_hWnd,NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
	return TRUE;
}
LRESULT CSkinFrame::OnWndMsg(UINT msg,WPARAM wp,LPARAM lp)
{
	switch(msg)
	{
	case WM_CREATE:
		Default();
		if(m_bMenu)
			SetMenu(m_hWnd,NULL);
		return 0;
	}
	return CSkinWnd::OnWndMsg(msg,wp,lp);
}
/******************************************
* 函数名 : OnTimter
* 功能	 :  
*******************************************/
void CSkinFrame::OnTimter(UINT_PTR nIDEvent)
{
	if(nIDEvent == 9999)
	{
		CPoint pt;
		GetCursorPos(&pt);
		UINT uHit = OnNcHitTest(pt);
		if(uHit != HTMENU)
		{
			KillTimer(m_hWnd,9999);
			m_menuBar.m_pHot = NULL;
			m_menuBar.m_pPressed = NULL;
			m_menuBar.DrawMenuBar();
			m_bInMenu = FALSE;
		}
	}
	Default();
}
/******************************************
* 函数名 : OnNcMouseMove
* 功能	 : 非客户区鼠标移动 
*******************************************/
void CSkinFrame::OnNcMouseMove( UINT nHitTest, const CPoint& point1 )
{
    CPoint point = point1;
	CWindowDC dc(CWnd::FromHandle(m_hWnd));
	switch(nHitTest)
	{
	case HTMAXBUTTON:
		if(!m_bTitle || !m_bMaxBtn)
			return;
		if(m_nMaxBtnState != keWinButtonHover)
		{
			m_nMaxBtnState		= keWinButtonHover;
			m_nMinBtnState		= keWinButtonNormal;
			m_nCloseBtnState	= keWinButtonNormal;
			m_nHelpBtnState		= keWinButtonNormal;
			DrawWindowButton(&dc);
		}
		break;
	case HTMINBUTTON:
		if(!m_bTitle || !m_bMinBtn)
			return;
		if(m_nMinBtnState != keWinButtonHover)
		{
			m_nMinBtnState = keWinButtonHover;
			m_nMaxBtnState		= keWinButtonNormal;
			m_nCloseBtnState	= keWinButtonNormal;
			m_nHelpBtnState		= keWinButtonNormal;
			DrawWindowButton(&dc);
		}

		break;
	case HTCLOSE:
		if(!m_bTitle || !m_bCloseBtn)
			return;		
		if(m_nCloseBtnState != keWinButtonHover)
		{
			m_nCloseBtnState = keWinButtonHover;
			m_nMaxBtnState		= keWinButtonNormal;
			m_nMinBtnState	= keWinButtonNormal;
			m_nHelpBtnState		= keWinButtonNormal;
			DrawWindowButton(&dc);
		}

		break;
	case HTHELP:
		if(!m_bTitle || !m_bCloseBtn)
			return;		
		if(m_nHelpBtnState != keWinButtonHover)
		{
			m_nHelpBtnState		= keWinButtonHover;
			m_nMaxBtnState		= keWinButtonNormal;
			m_nMinBtnState		= keWinButtonNormal;
			m_nCloseBtnState	= keWinButtonNormal;
			DrawWindowButton(&dc);
		}
		
		break;

	case HTHSCROLL:
		{
			int xoffset = 0, yoffset = 0;
			CRect rtClient,rtWindow;
			GetClientRect(&rtClient);
			ClientToScreen(&rtClient);
			GetWindowRect(&rtWindow);

			xoffset = rtClient.left - rtWindow.left;
			yoffset = rtClient.top - rtWindow.top;
			::ScreenToClient(m_hWnd, &point );
			point.x += xoffset;
			point.y += yoffset;
			SCROLL_HITTEST test = ScrollHitTest(SB_HORZ,point,FALSE);

			if(test == SCROLL_TOP_ARROW)
			{
				m_nHArrowLeftState = keScrollHover;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}
			else if(test == SCROLL_BOTTOM_ARROW)
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollHover;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}
			else if(test == SCROLL_THUMB)
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollHover;
				DrawHScrollBar(&dc);
			}
			else
			{
				m_nHArrowLeftState = keScrollNormal;
				m_nHArrowRightState = keScrollNormal;
				m_nHThumbState = keScrollNormal;
				DrawHScrollBar(&dc);
			}

			m_nVArrowTopState = keScrollNormal;
			m_nVArrowBottomState = keScrollNormal;
			m_nVThumbState = keScrollNormal;
			if(m_bVScroll)		
				DrawVScrollBar(&dc);
		}
		break;
	case HTVSCROLL:
		{
			int xoffset = 0, yoffset = 0;
			CRect rtClient,rtWindow;
			GetClientRect(&rtClient);
			ClientToScreen(&rtClient);
			GetWindowRect(&rtWindow);

			xoffset = rtClient.left - rtWindow.left;
			yoffset = rtClient.top - rtWindow.top;
			::ScreenToClient(m_hWnd, &point );
			point.x += xoffset;
			point.y += yoffset;
			SCROLL_HITTEST test = ScrollHitTest(SB_VERT,point,FALSE);

			if(test == SCROLL_TOP_ARROW)
			{
				m_nVArrowTopState = keScrollHover;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			else if(test == SCROLL_BOTTOM_ARROW)
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollHover;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			else if(test == SCROLL_THUMB)
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollHover;
				DrawVScrollBar(&dc);
			}
			else
			{
				m_nVArrowTopState = keScrollNormal;
				m_nVArrowBottomState = keScrollNormal;
				m_nVThumbState = keScrollNormal;
				DrawVScrollBar(&dc);
			}
			m_nHArrowLeftState = keScrollNormal;
			m_nHArrowRightState = keScrollNormal;
			m_nHThumbState = keScrollNormal;
			if(m_bHScroll)
				DrawHScrollBar(&dc);
		}
		break;
	case HTMENU:
		{
			CRect rtWindow;
			GetWindowRect(&rtWindow);
			point.Offset(-rtWindow.left,-rtWindow.top);
			m_menuBar.OnMouseMove(HTMENU,point);
			if(!m_bInMenu)
			{
				SetTimer(m_hWnd,9999,20,NULL);
				m_bInMenu = TRUE;
			}
		}
		break;
	default:
		if(m_bMenu &&(m_menuBar.m_pHot || m_menuBar.m_pPressed))
		{
			m_menuBar.m_pHot = NULL;
			m_menuBar.m_pPressed = NULL;
			m_menuBar.DrawMenuBar();
		}
		if(m_nCloseBtnState != keWinButtonNormal || m_nMaxBtnState != keWinButtonNormal || m_nMinBtnState != keWinButtonNormal
			|| m_nHelpBtnState != keWinButtonNormal ||m_nHArrowLeftState != keScrollNormal ||m_nHArrowRightState != keScrollNormal
			|| m_nHThumbState != keScrollNormal || m_nVArrowTopState != keScrollNormal || m_nVArrowBottomState != keScrollNormal
			|| m_nVThumbState != keScrollNormal)
		{
			m_nCloseBtnState	= keWinButtonNormal;
			m_nMaxBtnState		= keWinButtonNormal;
			m_nMinBtnState		= keWinButtonNormal;
			m_nHelpBtnState		= keWinButtonNormal;
			DrawWindowButton(&dc);

			m_nVArrowTopState = keScrollNormal;
			m_nVArrowBottomState = keScrollNormal;
			m_nVThumbState = keScrollNormal;
			if(m_bVScroll)		
				DrawVScrollBar(&dc);

			m_nHArrowLeftState = keScrollNormal;
			m_nHArrowRightState = keScrollNormal;
			m_nHThumbState = keScrollNormal;
			if(m_bHScroll)
				DrawHScrollBar(&dc);
		}
		break;
	}
}
void CSkinFrame::OnMouseMove( UINT nFlags, const CPoint&point )
{
	Default();
	if(m_bMenu &&(m_menuBar.m_pHot || m_menuBar.m_pPressed))
	{
		m_menuBar.m_pHot = NULL;
		m_menuBar.m_pPressed = NULL;
		m_menuBar.DrawMenuBar();
	}
	if(m_nCloseBtnState != keWinButtonNormal || m_nMaxBtnState != keWinButtonNormal 
		||m_nHelpBtnState != keWinButtonNormal ||m_nMinBtnState != keWinButtonNormal)
	{
		CWindowDC dc(CWnd::FromHandle(m_hWnd));
		m_nCloseBtnState	= keWinButtonNormal;
		m_nMaxBtnState		= keWinButtonNormal;
		m_nMinBtnState		= keWinButtonNormal;
		m_nHelpBtnState		= keWinButtonNormal;
		DrawWindowButton(&dc);
	}
	if(m_nHArrowLeftState != keScrollNormal ||m_nHArrowRightState != keScrollNormal
		|| m_nHThumbState != keScrollNormal )
	{
		CWindowDC dc(CWnd::FromHandle(m_hWnd));

		m_nVArrowTopState = keScrollNormal;
		m_nVArrowBottomState = keScrollNormal;
		m_nVThumbState = keScrollNormal;
		if(m_bVScroll)		
			DrawVScrollBar(&dc);
	}
	if(m_nVArrowTopState != keScrollNormal|| m_nVArrowBottomState != keScrollNormal
		|| m_nVThumbState != keScrollNormal)
	{
		CWindowDC dc(CWnd::FromHandle(m_hWnd));

		m_nHArrowLeftState = keScrollNormal;
		m_nHArrowRightState = keScrollNormal;
		m_nHThumbState = keScrollNormal;
		if(m_bHScroll)
			DrawHScrollBar(&dc);
	}
}
/******************************************
* 函数名 : OnNcLButtonUp
* 功能	 : 非客户区放开鼠标左键 
*******************************************/
void CSkinFrame::OnNcLButtonUp( UINT nHitTest, const CPoint&point )
{
	Default();
	
}
/******************************************
* 函数名 : OnNcLButtonDown
* 功能	 : 非客户区按下鼠标左键 
*******************************************/
void CSkinFrame::OnNcLButtonDown( UINT nHitTest, const CPoint&point )
{
	LRESULT result = 0;
	CWindowDC dc(CWnd::FromHandle(m_hWnd));
	MSG msg;
	UINT nCurrentHit = HTNOWHERE;
	switch(nHitTest)
	{
	case HTMAXBUTTON:
		if(!m_bMaxBtn)
			return;
		m_nSelBtnType = keMax;
		m_nMaxBtnState = keWinButtonPressed;
		DrawWindowButton(&dc);
		SetCapture(m_hWnd);
		while(TRUE)
		{
			int nOldMaxBtnState = m_nMaxBtnState;
			if (!GetMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
			if (CallMsgFilter( &msg, MSGF_MAX )) continue;

			if(msg.message == WM_LBUTTONUP)
			{
				nCurrentHit = OnNcHitTest(msg.pt);
				if(nCurrentHit == HTMAXBUTTON)
					m_nMaxBtnState = keWinButtonHover;
				else
					m_nMaxBtnState = keWinButtonNormal;
				if (m_nMaxBtnState != nOldMaxBtnState)
					DrawWindowButton(&dc);
				break;
			}

			if(msg.message != WM_MOUSEMOVE)
				continue;

			if(OnNcHitTest( msg.pt ) == nHitTest)
				m_nMaxBtnState = keWinButtonPressed;
			else
				m_nMaxBtnState = keWinButtonNormal;
			if (m_nMaxBtnState != nOldMaxBtnState)
				DrawWindowButton(&dc);
		}
		if(nCurrentHit == HTMAXBUTTON)
			SendMessage( m_hWnd,WM_SYSCOMMAND,
			IsZoomed(m_hWnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
		m_nMaxBtnState = keWinButtonNormal;
		DrawWindowButton(&dc);
		ReleaseCapture();
		break;
	case HTMINBUTTON:
		if(!m_bMinBtn)
			return;
		m_nSelBtnType = keMin;
		m_nMinBtnState = keWinButtonPressed;
		DrawWindowButton(&dc);
		SetCapture(m_hWnd);
		while(TRUE)
		{
			int nOldMinBtnState = m_nMinBtnState;
			if (!GetMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
			if (CallMsgFilter( &msg, MSGF_MAX )) continue;

			if(msg.message == WM_LBUTTONUP)
			{
				nCurrentHit = OnNcHitTest(msg.pt);
				if(nCurrentHit == HTMINBUTTON)
					m_nMinBtnState = keWinButtonHover;
				else
					m_nMinBtnState = keWinButtonNormal;
				if (m_nMinBtnState != nOldMinBtnState)
					DrawWindowButton(&dc);
				break;
			}

			if(msg.message != WM_MOUSEMOVE)
				continue;

			if(OnNcHitTest( msg.pt ) == nHitTest)
				m_nMinBtnState = keWinButtonPressed;
			else
				m_nMinBtnState = keWinButtonNormal;
			if (m_nMinBtnState != nOldMinBtnState)
				DrawWindowButton(&dc);
		}
		
		if (nCurrentHit == HTMINBUTTON)
			SendMessage( m_hWnd,WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
		m_nMinBtnState = keWinButtonNormal;
		DrawWindowButton(&dc);
		ReleaseCapture();
		break;
	case HTCLOSE:
		if(!m_bCloseBtn)
			return;
		m_nSelBtnType = keClose;
		m_nCloseBtnState = keWinButtonPressed;
		DrawWindowButton(&dc);
		SetCapture(m_hWnd);

		while(TRUE)
		{
			int nOldCloseBtnState = m_nCloseBtnState;
			if (!GetMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
			if (CallMsgFilter( &msg, MSGF_MAX )) continue;

			if(msg.message == WM_LBUTTONUP)
			{
				nCurrentHit = OnNcHitTest(msg.pt);
				if(nCurrentHit == HTCLOSE)
					m_nCloseBtnState = keWinButtonHover;
				else
					m_nCloseBtnState = keWinButtonNormal;
				if (m_nCloseBtnState != nOldCloseBtnState)
					DrawWindowButton(&dc);
				break;
			}

			if(msg.message != WM_MOUSEMOVE)
				continue;

			if(OnNcHitTest( msg.pt ) == nHitTest)
				m_nCloseBtnState = keWinButtonPressed;
			else
				m_nCloseBtnState = keWinButtonNormal;
			if (m_nCloseBtnState != nOldCloseBtnState)
				DrawWindowButton(&dc);
		}
		if (nCurrentHit == HTCLOSE)
			SendMessage(m_hWnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
		ReleaseCapture();
		break;
	case HTHELP:
		m_nNcMouseState = keMouseDown;
		m_nSelBtnType = keHelp;
		m_nHelpBtnState = keWinButtonPressed;
		DrawWindowButton(&dc);
		SetCapture(m_hWnd);

		while(TRUE)
		{
			int nOldHelpBtnState = m_nHelpBtnState;
			if (!GetMessage( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
			if (CallMsgFilter( &msg, MSGF_MAX )) continue;

			if(msg.message == WM_LBUTTONUP)
			{
				m_nHelpBtnState = keMouseNormal;
				nCurrentHit = OnNcHitTest(msg.pt);
				if(nCurrentHit == HTHELP)
					m_nHelpBtnState = keWinButtonHover;
				else
					m_nHelpBtnState = keWinButtonNormal;
				if (m_nHelpBtnState != nOldHelpBtnState)
					DrawWindowButton(&dc);
				break;
			}

			if(msg.message != WM_MOUSEMOVE)
				continue;

			if(OnNcHitTest( msg.pt ) == nHitTest)
				m_nHelpBtnState = keWinButtonPressed;
			else
				m_nHelpBtnState = keWinButtonNormal;
			if (m_nHelpBtnState != nOldHelpBtnState)
				DrawWindowButton(&dc);
		}
		ReleaseCapture();

		break;

	case HTHSCROLL:
		SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_HSCROLL, MAKELPARAM(point.x,point.y) );
		break;
	case HTVSCROLL:
		SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_VSCROLL, MAKELPARAM(point.x,point.y) );
		break;

	case HTMENU:
		SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_MOUSEMENU, MAKELPARAM(point.x,point.y) );
	//	Default();
		break;
	default:
		Default();
		break;
	}

//	DrawCaption(&dc);
}

//*****************************************************************************
// 复制菜单，因为系统菜单的特殊性，主要用于复制系统菜单
//*****************************************************************************
HMENU CSkinFrame::CopyMenuFrom(HMENU hMenuSrc)
{
	if(hMenuSrc == NULL)
	{
		return NULL;
	}
	HMENU hMenu = ::CreatePopupMenu();
	if(hMenu == NULL)
	{
		return NULL;
	}

	MENUITEMINFO mii;
	memset(&mii, 0, sizeof(mii));
	mii.cbSize = sizeof(mii);

#ifndef MIIM_BITMAP
#define MIIM_BITMAP      0x00000080
#endif
	mii.fMask = MIIM_STATE | MIIM_DATA | MIIM_BITMAP; 


	int nCount = ::GetMenuItemCount(hMenuSrc);

	
	for(int i = 0; i < nCount; ++i)
	{
		UINT nID = GetMenuItemID(hMenuSrc, i);
		TCHAR *szLabel = NULL;
		int nLen = GetMenuString(hMenuSrc, i, szLabel, 0, MF_BYPOSITION);
		szLabel = new TCHAR[nLen + 1];

		GetMenuString(hMenuSrc, i, szLabel, nLen + 1, MF_BYPOSITION);

		UINT nFlags = (nID == 0) ? MF_SEPARATOR : (nID == (UINT)-1) ? MF_POPUP : MF_STRING;

		
		if (nFlags == MF_POPUP)
		{
			HMENU hPopup = CopyMenuFrom(GetSubMenu(hMenuSrc, i));
			ASSERT (hPopup);

			nID = (UINT)hPopup;
		}

		AppendMenu(hMenu, nFlags, nID, szLabel);

		::GetMenuItemInfo(hMenuSrc, i, TRUE, &mii);
		::SetMenuItemInfo(hMenu, i, TRUE, &mii);
		delete []szLabel;
	}

	return hMenu;
}


//*****************************************************************************
// 鼠标右键响应 
//*****************************************************************************
void CSkinFrame::OnNcRButtonDown(UINT nHitTest, CPoint point)
{	
	switch(nHitTest)
	{
	case HTCAPTION:
	case HTSYSMENU:
		{
			HMENU hMenu = GetSystemMenu(m_hWnd, FALSE);
			HMENU hSysMenuCopy = CopyMenuFrom(hMenu);
			// TODO: ChongyangLee 2009/11/21
			// 下面应该修改菜单的状态，暂时先不修改了，因为...
						
			int nID = TrackPopupMenu(hSysMenuCopy,
				TPM_RIGHTBUTTON | TPM_RETURNCMD,
				point.x, point.y, 0, m_hWnd, NULL);
			if(nID > 0)
			{
				SendMessage(m_hWnd, WM_SYSCOMMAND, nID, 0);
			}
			DestroyMenu(hSysMenuCopy);
			Default();
			break;
		}
	default:
		Default();
		break;
	}
	
}




/******************************************
* 函数名 : OnNcLButtonDblClk
* 功能	 : 非客户区双击鼠标左键 
*******************************************/
void CSkinFrame::OnNcLButtonDblClk( UINT nHitTest, const CPoint&point )
{
	if (IsIconic(m_hWnd))
	{
		SendMessage(m_hWnd,WM_SYSCOMMAND, SC_RESTORE, 0);
		return;
	}
	if ( nHitTest == HTCAPTION && m_bSizable )
	{
		if(IsZoomed(m_hWnd))
			SendMessage(m_hWnd,WM_SYSCOMMAND, SC_RESTORE, 0);
		else
			SendMessage(m_hWnd,WM_SYSCOMMAND, SC_MAXIMIZE,0);
		OnNcPaint(0);
	}
	else if(nHitTest == HTHSCROLL)
	{
		SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_HSCROLL, MAKELPARAM(point.x,point.y) );
	}
	else if(nHitTest == HTVSCROLL)
	{
		SendMessage( m_hWnd, WM_SYSCOMMAND, (WPARAM)SC_VSCROLL, MAKELPARAM(point.x,point.y) );
	}
	else
		Default();
}
/******************************************
* 函数名 : OnNcHitTest
* 功能	 : 当鼠标移动时调用此函数 
*******************************************/
UINT CSkinFrame::OnNcHitTest( const CPoint& point )
{
#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
#endif
	if(style & WS_MINIMIZE)
		return HTCAPTION;

	CRect rtWindow;
	CRect rtClient;
	CRect rtMargin = m_pSkinWindow->GetMargins();

	int nHHeight = GetSystemMetrics(SM_CYHSCROLL);
	int nVWidth = GetSystemMetrics(SM_CXVSCROLL);
	GetWindowRect(&rtWindow);
	GetClientRect(&rtClient);
	ClientToScreen(&rtClient);
	m_pSkinWindow->CalcPartsRect(rtWindow);

	if(rtClient.PtInRect(point))
		return HTCLIENT;
	if(m_bVScroll)
	{
		if(m_bLeftScroll)
			m_rtVScroll = CRect(rtClient.left - nVWidth,rtClient.top,rtClient.left,rtClient.bottom);
		else
			m_rtVScroll = CRect(rtClient.right,rtClient.top,rtClient.right + nVWidth,rtClient.bottom);
	
		if(m_rtVScroll.PtInRect(point))
			return HTVSCROLL;
	}

	if(m_bHScroll)
	{
		m_rtHScroll = CRect(rtClient.left,rtClient.bottom,rtClient.right,rtClient.bottom + nHHeight);
	
		if(m_rtHScroll.PtInRect(point))
			return HTHSCROLL;
	}
	
	if(m_bMenu)
	{
		int nMenuHeight = GetSystemMetrics(SM_CYMENU);
		m_rtMenu = CRect(rtWindow.left + rtMargin.left,rtWindow.top+ rtMargin.top,rtWindow.right - rtMargin.right,rtWindow.top + rtMargin.top + nMenuHeight);
		if(m_rtMenu.PtInRect(point))
			return HTMENU;
	}

	
	UINT uiHitTest = m_pSkinWindow->HitTest(point);
	if(!m_bTitle)
	{
		if(uiHitTest == HTSYSMENU || uiHitTest == HTHELP || 
			uiHitTest == HTMINBUTTON || uiHitTest == HTMAXBUTTON || 
			uiHitTest == HTCLOSE || uiHitTest == HTCAPTION  )
		return HTBORDER;
	}
	if(!m_bSizable)
	{
		if(uiHitTest == HTTOPLEFT || uiHitTest == HTTOPRIGHT || 
			uiHitTest == HTLEFT || uiHitTest == HTRIGHT || 
			uiHitTest == HTBOTTOMLEFT || uiHitTest == HTBOTTOM ||
			uiHitTest == HTBOTTOMRIGHT )
		uiHitTest = HTBORDER;
	}

	
	
		
	return uiHitTest;
}
/******************************************
* 函数名 : OnNcActivate
* 功能	 : 改变非客户区活动或非活动状态调用 
*******************************************/
BOOL CSkinFrame::OnNcActivate( BOOL bActive )
{
	m_bActive = bActive;
	if(!IsIconic(m_hWnd))
	{
		OnNcPaint(0);
	}
	if ( !bActive )
		return 1;
	else
		return 0;
	
}
/******************************************
* 函数名 : OnNcCalcSize
* 功能	 : 根据窗口大小计算客户区大小 
*******************************************/
void CSkinFrame::OnNcCalcSize( BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
	LPRECT lpRect = &(lpncsp->rgrc[0]);
#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
#endif
	SCROLLBAR *sb;

	m_bHScroll		= style & WS_HSCROLL;
	m_bVScroll		= style & WS_VSCROLL;

	if(m_bBorder)
	{
		lpncsp->rgrc[0].left += m_pSkinWindow->GetMargins().left;
		lpncsp->rgrc[0].top += m_pSkinWindow->GetMargins().top;
		lpncsp->rgrc[0].right -= m_pSkinWindow->GetMargins().right;
		lpncsp->rgrc[0].bottom -= m_pSkinWindow->GetMargins().bottom;

		lpncsp->rgrc[1] = lpncsp->rgrc[0];
	}

	if (m_bMenu)
		lpRect->top += GetSystemMetrics(SM_CYMENU);

    sb = GetScrollBarFromHwnd(m_hWnd, SB_VERT);

    if (sb)
    {

        if(sb->fScrollFlags & CSBS_VISIBLE)
        {
            if( lpRect->right - lpRect->left >= GetSystemMetrics(SM_CXVSCROLL))
            {
                if(m_bLeftScroll)
                    lpRect->left  += GetSystemMetrics(SM_CXVSCROLL);
                else
                    lpRect->right -= GetSystemMetrics(SM_CXVSCROLL);
            }

            sb->fScrollVisible = TRUE;
        }
        else
            sb->fScrollVisible = FALSE;
    }
    sb = GetScrollBarFromHwnd(m_hWnd, SB_HORZ);
    if (sb)
    {
        if (sb->fScrollFlags & CSBS_VISIBLE)
        {
            if( lpRect->bottom - lpRect->top > GetSystemMetrics(SM_CYHSCROLL))
                lpRect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
            sb->fScrollVisible = TRUE;
        }
        else
            sb->fScrollVisible = FALSE;
    }

}
void CSkinFrame::OnSize(UINT nType,int cx,int cy)
{
	OnNcPaint(NULL);
	Default();
}

void CSkinFrame::OnEnable(BOOL bEnable)
{
	Default();
//	OnNcPaint(NULL);
}
/******************************************
* 函数名 : OnNcPaint
* 功能	 : 当非客户需要重画时调用 
*******************************************/
void CSkinFrame::OnNcPaint(HRGN rgn1)
{
#ifdef _WIN64
	LONG_PTR style = GetWindowLongPtr(m_hWnd, GWL_STYLE);
	LONG_PTR exstyle = GetWindowLongPtr(m_hWnd, GWL_EXSTYLE);
#else
	DWORD style = GetWindowLong(m_hWnd, GWL_STYLE);
	DWORD exstyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
#endif
	m_bHScroll		= style & WS_HSCROLL;
	m_bVScroll		= style & WS_VSCROLL;
	m_bLeftScroll	= exstyle & WS_EX_LEFTSCROLLBAR;

	CWnd *pWnd = CWnd::FromHandle(m_hWnd);
	if(pWnd)
	{
        CAutoReleaseDC pDC(pWnd);
		pDC = pWnd->GetWindowDC();
		if(pDC->m_hDC)
		{
			CRect rtWindow;
			pWnd->GetWindowRect( rtWindow );
			CRect rtClient;
			GetClientRect(&rtClient);
			ClientToScreen(&rtClient);
			rtClient.OffsetRect(-rtWindow.left,-rtWindow.top);

			rtWindow.OffsetRect(-rtWindow.left,-rtWindow.top);

			pDC->SetBkMode(TRANSPARENT);
			HRGN hRGN = m_pSkinWindow->GetRgn(pDC,rtWindow);
			CRgn *pRgn = CRgn::FromHandle(hRGN);
			pDC->SelectClipRgn(pRgn);

			if(m_bTitle)
				DrawCaption(pDC);
			if(m_bMenu)
				DrawMenuBar(pDC);
			if(m_bHScroll)
				DrawHScrollBar(pDC);
			if(m_bVScroll)
				DrawVScrollBar(pDC);
			if(m_bBorder)
			{
				m_pSkinWindow->DrawLeft(pDC,rtWindow,m_bActive);
				m_pSkinWindow->DrawBottom(pDC,rtWindow,m_bActive);
				m_pSkinWindow->DrawRight(pDC,rtWindow,m_bActive);
			}

			if(m_bHScroll && m_bVScroll)
			{
				CRect rtSizing;
				if(m_bLeftScroll)
				{
					rtSizing = CRect(rtClient.right - GetSystemMetrics(SM_CXVSCROLL), rtClient.bottom,rtClient.right,rtClient.bottom + GetSystemMetrics(SM_CYHSCROLL));
				}
				else
				{
					rtSizing = CRect(rtClient.right, rtClient.bottom,rtClient.right + GetSystemMetrics(SM_CXVSCROLL),
						rtClient.bottom + GetSystemMetrics(SM_CYHSCROLL));
				}
				m_pSkinScrollBar->DrawSizing(pDC,rtSizing);
			}
			if(pRgn)
				pRgn->DeleteObject();
		}	
	}
	
}
/******************************************
* 函数名 : OnEraseBkgnd
* 功能	 :  
*******************************************/
BOOL CSkinFrame::OnEraseBkgnd(CDC *pDC)
{
	Default();
	return TRUE;
}
/******************************************
* 函数名 : OnSysCommand
* 功能	 :  
*******************************************/
void CSkinFrame::OnSysCommand(UINT nID,LPARAM lParem)
{
	if(nID == SC_VSCROLL )
	{
		TrackScrollBar(SB_VERT,CPoint(LOWORD(lParem),HIWORD(lParem)));
	}
	else if(nID == SC_HSCROLL)
	{
		TrackScrollBar(SB_HORZ,CPoint(LOWORD(lParem),HIWORD(lParem)));
	}
	else if(nID == SC_MOUSEMENU)
	{
		CPoint pt(LOWORD(lParem),HIWORD(lParem));
		CRect rtWindow;
		GetWindowRect(&rtWindow);
		pt.Offset(-rtWindow.left,-rtWindow.top);
		m_menuBar.OnLButtonDown(HTMENU,pt);
	}
	else if(nID == SC_MINIMIZE)
	{
		if (m_hWnd == GetForegroundWindow())
			ShowOwnedPopups(m_hWnd,FALSE);
		ShowWindow( m_hWnd, SW_MINIMIZE );
	}
	else if(nID == SC_MAXIMIZE)
	{
		if (IsIconic(m_hWnd) && m_hWnd == GetForegroundWindow())
			ShowOwnedPopups(m_hWnd,TRUE);
		ShowWindow( m_hWnd, SW_MAXIMIZE );
	}
	else if(nID == SC_RESTORE)
	{
		if (IsIconic(m_hWnd) && m_hWnd == GetForegroundWindow())
			ShowOwnedPopups(m_hWnd,TRUE);
		ShowWindow( m_hWnd, SW_RESTORE );
	}
	else if(nID == SC_CLOSE)
	{
		SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
		return ;
	}
	else
		Default();
}
/******************************************
* 函数名 : OnSetText
* 功能	 :  
*******************************************/
void CSkinFrame::OnSetText(WPARAM wp,LPARAM lp)
{
	Default();
	CWnd *pWnd = CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(pWnd);
	pDC = pWnd->GetWindowDC();
//	DrawCaption(pDC);
	OnNcPaint(NULL);
}
/******************************************
* 函数名 : OnSetIcon
* 功能	 : 设置窗口的图标 
*******************************************/
LRESULT CSkinFrame::OnSetIcon(UINT nFlag,HICON hIcon)
{
	Default();
	CWnd *pWnd = CWnd::FromHandle(m_hWnd);
    CAutoReleaseDC pDC(pWnd);
	pDC = pWnd->GetWindowDC();
	DrawCaption(pDC);
	return 0;
}
/******************************************
* 函数名 : DrawWindowButton
* 功能	 :  
*******************************************/
void CSkinFrame::DrawWindowButton(CDC *pDC)
{
	CRect wr;
	GetWindowRect(&wr);
	wr.OffsetRect(-wr.left,-wr.top);

	if(m_bTitle && m_bCloseBtn)
		m_pSkinWindow->DrawCloseButton(pDC,wr,m_nCloseBtnState);
	if(m_bTitle && m_bMaxBtn)
	{
		if(IsZoomed(m_hWnd))
			m_pSkinWindow->DrawRestoreButton(pDC,wr,m_nMaxBtnState);
		else
			m_pSkinWindow->DrawMaxButton(pDC,wr,m_nMaxBtnState);
	}
	if(m_bTitle && m_bMinBtn)
		m_pSkinWindow->DrawMinButton(pDC,wr,m_nMinBtnState);
}
/******************************************
* 函数名 : DrawCaption
* 功能	 :  
*******************************************/
void CSkinFrame::DrawCaption(CDC *pDC)
{
	CWnd *pWnd = CWnd::FromHandle(m_hWnd);
	CRect rtWindow;
	GetWindowRect(&rtWindow);
	rtWindow.OffsetRect(-rtWindow.left,-rtWindow.top);

	CRect			rtMargins = m_pSkinWindow->GetMargins();
	CRect			rtParts;	
	rtParts.left	= rtWindow.left + rtMargins.left;
	rtParts.top		= rtWindow.top;
	rtParts.right	= rtWindow.right - rtMargins.right;
	rtParts.bottom	= rtWindow.top + rtMargins.top;

	CMemDC memDc(pDC,&rtParts);

	if(!m_pSkinWindow->DrawTop(&memDc,rtWindow,m_bActive))
		m_pSkinWindow->DrawTop(&memDc,rtWindow,TRUE);

	if(m_bCloseBtn)
		m_pSkinWindow->DrawCloseButton(&memDc,rtWindow,m_nCloseBtnState);
	if(m_bMaxBtn)
	{
		if(IsZoomed(m_hWnd))
			m_pSkinWindow->DrawRestoreButton(&memDc,rtWindow,m_nMaxBtnState);
		else
			m_pSkinWindow->DrawMaxButton(&memDc,rtWindow,m_nMaxBtnState);
	}
	if(m_bMinBtn)
		m_pSkinWindow->DrawMinButton(&memDc,rtWindow,m_nMinBtnState);

	HICON hIcon = pWnd->GetIcon(FALSE);
	if (hIcon == NULL) {
	#ifdef _WIN64
		hIcon = (HICON)GetClassLongPtr(m_hWnd, GCLP_HICON);
	#else
		hIcon = (HICON)GetClassLong(m_hWnd, GCL_HICON);

	#endif
	}
	CRect rtTitleText;
	if(hIcon != NULL)
	{
		CPoint pt;
		pt.x = rtParts.left + 2;
		pt.y = (rtParts.bottom + rtParts.top - GetSystemMetrics(SM_CYSMICON)) / 2;
		DrawIconEx(memDc.m_hDC,pt.x,pt.y,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON), 
						0, 0, DI_NORMAL);
	//	rtTitleText.SetRect(rtParts.left + rtParts.Height()+5,rtParts.top,rtParts.right - 60,rtParts.bottom);
		rtTitleText = rtParts;
		rtTitleText.left = rtParts.bottom - rtParts.top;
	}
	else
	{
		rtTitleText = rtParts;
		rtTitleText.left = 5;
	}


	CString strText;
	int nOldMode = memDc.SetBkMode(TRANSPARENT);
	pWnd->GetWindowText(strText);

	CFont TitleFont;
	NONCLIENTMETRICS nif;
	nif.cbSize = sizeof(nif);
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&nif,0);
	TitleFont.CreateFontIndirect(&nif.lfSmCaptionFont);
	CFont *pOldFont = memDc.SelectObject(&TitleFont);
	
	

	memDc.SetTextColor(RGB(0,0,0));
	memDc.DrawText(strText,rtTitleText,DT_LEFT | DT_VCENTER|DT_SINGLELINE);

	memDc.SelectObject(&pOldFont);
	memDc.SetBkMode(nOldMode);

	if(m_bMenu)
		DrawMenuBar(pDC);
}

void CSkinFrame::DrawMenuBar(CDC *pDC)
{
	m_menuBar.DrawMenuBar();
}
void CSkinFrame::TrackMenuBar( const CPoint& point1 )
{
    POINT point = point1;
	INT xoffset = 0, yoffset = 0;
	CRect rtWindow;
	
	GetWindowRect(&rtWindow);

	
	point.x -= rtWindow.left;
	point.y -= rtWindow.top;
	

	m_menuBar.OnLButtonDown(HTMENU,point);

}
